package com.junbao.message.domain.model;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;
import java.util.UUID;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;
import com.junbao.commom.http.HttpUtils;
import com.junbao.commom.sign.md5.MD5Utils;
import com.junbao.commom.util.DateFormatUtil;
import com.junbao.commom.util.JsonUtils;
import com.junbao.message.domain.enums.ACKFlag;
import com.junbao.message.domain.enums.ConfirmWay;
import com.junbao.message.domain.enums.IsDead;
import com.junbao.message.domain.enums.MessageConfirmStatus;
import com.junbao.message.domain.enums.NotifyDataType;
import com.junbao.message.domain.enums.NotifyStatus;
import com.junbao.message.domain.enums.NotifyWay;
import com.junbao.message.infrastructure.command.ConcreteCommand;
import com.junbao.message.infrastructure.command.MessageReceiver;
import com.junbao.message.infrastructure.prop.MessageConfig;
import com.junbao.message.infrastructure.util.IdCreater;
import com.junbao.message.infrastructure.util.IdWorker;

/**
 * 通知消息
 * 
 * @author yilin
 *    
 */
public class NotifyMessage extends Entity {
 
    private static final long serialVersionUID = -2937053824816980961L;
 
    private static final IdCreater msf = new IdCreater(new Random().nextInt(255), new Random().nextInt(3));
    
    private static final MessageConfig CONFIG = new MessageConfig();
    
    private static final Logger LOGGER = LoggerFactory.getLogger(NotifyMessage.class);
 
    // 成功标识
    private static final String SUCCESS_FLAG = "0000";
    // 重试间隔时间(单位毫秒)
    private static final long RETRYINTERVALTIME = 60 * 1000;
    // 最大重试次数
    public static final Integer MAX_RETRY_COUNT = 5;
    //默认消息最大确认次数
    public static final Integer DEFAULT_CONFIRM_MAX_COUNT = 3;
    //默认消息确认次数
    public static final Integer DEFAULT_CONFIRM_COUNT = 0;
    //默认补偿时间为5s
    public static final Integer DEFAULT_OFFSET_TIME = 5*1000;
    //消息编号
    private String messageNo;
    // 消息序列号
    private String messageSquece;
    // 通知方式
    private NotifyWay notifyWay;
    // 通知地址(REST)
    private String notifyUrl;
    // 通知数据类型
    private NotifyDataType notifyDataType;
    // 通知数据
    private String notifyData;
    //消息确认最大重试次数
    private Integer confirmCount;
    // 最大重试次数
    private Integer retryMaxCount;
    // 重试次数
    private Integer retryCount;
    // 下一次重试时间
    private Date nextRetryTime;
    // 通知状态
    private NotifyStatus notifyStatus;
    // 是否死亡
    private IsDead isDead;
    // 失败备注
    private String failRemark;
    // 待通知消息确认方式（REST）
    private ConfirmWay confirmWay;
    // 待通知消息确认地址
    private String confirmReqUrl;
    private Date createDate;
    private Date updateDate;
    private Integer deleteFlag;
    
    public NotifyMessage() {
        super(String.valueOf(msf.nextId()).substring(1));
    }
 
    public NotifyMessage(String messageNo,NotifyWay notifyWay, String notifyDta,String notifyUrl) {
        super(String.valueOf(msf.nextId()).substring(1));
        setMessageNo(messageNo);
        setMessageSquece(buildMessageSquece());
        setNotifyWay(notifyWay);
        setNotifyUrl(notifyUrl);
        setNotifyData(notifyDta);
        setNotifyDataType(NotifyDataType.JSON);
        this.retryMaxCount = MAX_RETRY_COUNT;
        initRetryCount();
        initConfirmCount();
        setNotifyStatus(NotifyStatus.WAIT_SEND);
        setIsDead(IsDead.NO);
        setCreateDate(new Date());
        setUpdateDate(new Date());
        setDeleteFlag(0);
    }
    
    private void initConfirmCount() {
		this.confirmCount = 0;
	}

	public NotifyMessage(String messageNo,NotifyWay notifyWay, String notifyDta,String notifyUrl,NotifyStatus notifyStatus) {
        super(String.valueOf(msf.nextId()).substring(1));
        setMessageNo(messageNo);
        setMessageSquece(buildMessageSquece());
        setNotifyWay(notifyWay);
        setNotifyUrl(notifyUrl);
        setNotifyData(notifyDta);
        setNotifyDataType(NotifyDataType.JSON);
        this.retryMaxCount = MAX_RETRY_COUNT;
        initRetryCount();
        setNotifyStatus(notifyStatus);
        setIsDead(IsDead.NO);
        setCreateDate(new Date());
        setUpdateDate(new Date());
        setDeleteFlag(0);
    }
 
    /**
     * 发送消息
     * 当接收消息编码为“0000”并且当消息ack标识未“0”时，消息才为消息消息成功。
     * @return
     */
    public void sendMessage() {
        MessagSendResult sendTag = null;
        if (notifyWayIsRest()) {
            sendTag = notifyByRest();
        }
        updateMessageBySendTag(sendTag);
    }
 
 
    /**
     * 根据消息发送结果更新消息
     * @param sendTag 消息发送结果
     */
    private void updateMessageBySendTag(MessagSendResult messagSendResult) {
        if (messagSendResult == null) {
            retryCountCalculate();
            nextRetryTimeCalculate();
            this.failRemark = "messagSendResult 返回结果为空！";
            new ConcreteCommand(new MessageReceiver(this)).messageRetry();
            return;
        }
        if (!messagSendResult.isSuccess()) {
            retryCountCalculate();
            nextRetryTimeCalculate();
            this.failRemark = messagSendResult.getResultMsg();
            new ConcreteCommand(new MessageReceiver(this)).messageRetry();
            return;
        }else {
            if (messagSendResult.isNeedAck()) {
                markStatusToSended();
                this.failRemark = messagSendResult.getResultMsg();
            }else {
                this.failRemark = "success";
                markStatsToSuccess();
            }
        }
    }
 
    /**
     * 消息确认
     */
    public void confirmMessage() {
         ConfirmResult confirmResult = null;
        if (cofirmWayIsRest()) {
            confirmResult = confirmByRest();
        }
        updateMessageStatuByConfirmResult(confirmResult);
    }
 
    /**
     * 根据消息确认结果更新消息信息
     * @param confirmResult 消息确认结果
     */
    private void updateMessageStatuByConfirmResult(ConfirmResult confirmResult) {
        if (confirmResult == null) {
            this.failRemark = "根据消息确认结果更新消息信息失败，消息确认结果为空！";
            confirmCountCalculate();
            new ConcreteCommand(new MessageReceiver(this)).messageConfirm();
            return;
        }
        if (!confirmResult.isSuccess()) {
            this.failRemark = confirmResult.getMessage();
            confirmCountCalculate();
            new ConcreteCommand(new MessageReceiver(this)).messageConfirm();
            return;
        }else {
            if (confirmResult.messageIsNeedSend()) {
                setNextRetryTime(new Date());
                markStatsToWaitSend();
                return;
            }else {
                this.failRemark = confirmResult.getMessage();
                markMessageToDead();
                return;
            }    
        }
    }
 
    /**
     * 通过发送http请求进行通知
     * 
     * @return
     */
    private MessagSendResult notifyByRest() {
        MessagSendResult messagSendResult = null;
        try {
            String requestResult = null;
            if (this.notifyDataType == NotifyDataType.JSON) {
                //requestResult = HttpUtilsByHttpclient.post(this.notifyUrl, buildNotifyRequestParam(), HttpUtilsByHttpclient.JSONTYPE);
                requestResult = httpRequestSend(this.notifyUrl, buildNotifyRequestParam());
            }
            LOGGER.info("消息序列号： "+this.messageSquece+" 收到目标系统返回消息： "+requestResult );
            this.failRemark = requestResult;
            if (!StringUtils.isEmpty(requestResult)) {
                net.sf.json.JSONObject sendResult = net.sf.json.JSONObject.fromObject(requestResult);
                JsonUtils.containsKeysAndKeyValueIsEmpty(sendResult, "result_code","result_msg","sign_parm","sign");
                if (!MD5Utils.signBuildByStrCheck(sendResult.getString("sign_parm").substring(5,15), CONFIG.get("message.md5.key"),sendResult.getString("sign"))) {
                    LOGGER.info("返回结果签名异常，返回参数:"+requestResult);
                    this.failRemark = "返回结果签名异常，返回参数:"+requestResult;
                    return new MessagSendResult("9999", "返回结果签名异常，返回参数:"+requestResult);
                }
                if (!sendResult.getString("result_code").equals(SUCCESS_FLAG)) {
                    return new MessagSendResult("9999", sendResult.getString("result_msg"));
                }
                JsonUtils.containsKeysAndKeyValueIsEmpty(sendResult, "ack_flag");
                messagSendResult = new MessagSendResult(sendResult.getString("result_code"), 
                        sendResult.getString("result_msg"), 
                        sendResult.getInt("ack_flag"));
            }
        } catch (Exception e) {
            LOGGER.info("通知目标系统接收参数异常！消息序列号=> "+this.messageSquece);
            LOGGER.error("通知目标系统接收参数异常！",e);
            messagSendResult = new MessagSendResult("9999", "通知目标系统接收参数异常！");
        }
        return messagSendResult;
    }
    
 
    /**
     * 构建通知请求参数
     * @return
     */
    private String buildNotifyRequestParam() {
        String uuidStr = UUID.randomUUID().toString().replace("-", "");
        String signParm = uuidStr.substring(5, 15);
        Map<String, String> notifyRequestParam = new LinkedHashMap<String, String>();
        notifyRequestParam.put("message_squece", this.messageSquece);
        notifyRequestParam.put("notify_way", String.valueOf(this.notifyWay.getCode()));
        notifyRequestParam.put("notify_data_type", String.valueOf(this.notifyDataType.getCode()));
        notifyRequestParam.put("notify_data", this.notifyData);
        notifyRequestParam.put("sign_parm", uuidStr);
        notifyRequestParam.put("sign", MD5Utils.signBuildByStr(signParm, CONFIG.get("message.md5.key")));
        return JSONObject.toJSONString(notifyRequestParam);
    }
    
    /**
     * rest方式确认消息
     * 
     * @return
     */
    private ConfirmResult confirmByRest() {
        ConfirmResult confirmResult = null;
        try {
            //String confirmResultSource = HttpUtilsByHttpclient.post(this.confirmReqUrl, buildMessageConfrimParam(), HttpUtilsByHttpclient.JSONTYPE);
            String confirmResultSource = httpRequestSend(this.confirmReqUrl,buildMessageConfrimParam());
            LOGGER.info("消息确认编号： "+this.messageNo+" 收到主动方返回消息： "+confirmResultSource );
            if (StringUtils.isEmpty(confirmResultSource)) {
                LOGGER.info("消息确认失败，主动方返回数据为空，消息序列号： "+ this.messageSquece);
                return new ConfirmResult(ConfirmResult.FAIL_TAG, "消息确认失败，主动方返回数据为空，消息序列号： "+ this.messageSquece);
            }
            net.sf.json.JSONObject confirmResultJson = net.sf.json.JSONObject.fromObject(confirmResultSource);
            JsonUtils.containsKeysAndKeyValueIsEmpty(confirmResultJson, "result_code","result_msg");
            if (!confirmResultJson.getString("result_code").equals(SUCCESS_FLAG)) {
                return new ConfirmResult(ConfirmResult.FAIL_TAG, confirmResultJson.getString("result_msg"));
            }
            JsonUtils.containsKeysAndKeyValueIsEmpty(confirmResultJson, "send_flag");
            confirmResult = new ConfirmResult(confirmResultJson.getString("result_code"),
                    confirmResultJson.getString("result_msg"), 
                    MessageConfirmStatus.getMessageConfirmStatusByCode(confirmResultJson.getString("send_flag")));
        } catch (Exception e) {
            LOGGER.error("向主动方确认消息发送标识失败，消息序列号: "+ this.messageSquece, e);
            confirmResult = ConfirmResult.FAIL;
        }
        return confirmResult;
    }
    
    
    /**
     * 构建消息确认发送标识请求参数
     * @return
     */
    private String buildMessageConfrimParam() {
        Map<String, String> notifyRequestParam = new LinkedHashMap<String, String>();
        notifyRequestParam.put("message_no", this.messageNo);
        return JSONObject.toJSONString(notifyRequestParam);
    }
 
    /**
     * 构建rest通知方式
     * 
     * @param notifyUrl rest通知地址
     * @return
     */
    public NotifyMessage buildRestNotify(String notifyUrl) {
        setNotifyUrl(notifyUrl);
        return this;
    }
 
    /**
     * 是否是rest通知方式
     * 
     * @return
     */
    public boolean notifyWayIsRest() {
        return notifyWay == NotifyWay.REST;
    }
 
 
    /**
     * 重试次数计算,如果重试次数大于最大重试次数，将消息变更为死亡
     */
    public void retryCountCalculate() {
        this.retryCount = this.retryCount + 1;
        if (retryCount > retryMaxCount) {
            this.notifyStatus = NotifyStatus.FAIL;
        }
    }
    
    /**
     * 消息确认次数计算,如果消息确认次数大于最大消息确认次数，将消息变更为死亡
     */
    public void confirmCountCalculate() {
        this.confirmCount = this.confirmCount == 0 ? 1: this.confirmCount + 1;
        if (this.confirmCount > DEFAULT_CONFIRM_MAX_COUNT) {
            this.failRemark = "消息确认次数达到最大次数！";
            this.isDead = IsDead.YES;
        }
    }
 
    /**
     * 下次重试时间
     */
    public void nextRetryTimeCalculate() {
        long lastRetryTime = this.nextRetryTime == null ? new Date().getTime() : this.nextRetryTime.getTime();
        //如果下次执行时间小于当前时间，默认在当前时间加5s作为下一次执行时间。
        if (lastRetryTime < new Date().getTime()) {
            lastRetryTime = new Date().getTime() + DEFAULT_OFFSET_TIME;
        }
        long time = Long.valueOf((this.retryCount * RETRYINTERVALTIME));
        long timeStamp = lastRetryTime + time;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 这个是你要转成后的时间的格式
        String sd = sdf.format(new Date(timeStamp)); // 时间戳转换成时间
        try {
            this.nextRetryTime = DateFormatUtil.strFormatDate(sd, DateFormatUtil.DATE_FORMAT);
        } catch (ParseException e) {
            throw new RuntimeException("计算下一次重试实现错误!", e);
        }
    }
    
    /**
     * 获取下一次执行时间间隔，单位s
     *如果已经达到最大消息重试次数，3s后直接执行死亡消息变更。
     * @return
     */
    public int getNextRetryExecuteTime(){
        if (this.isGreaterThanMaxRetryCount()) {
            return 3;
        }
        if (this.nextRetryTime == null) {
        	this.nextRetryTime = new Date();
		}
        int intervalTime = (int) ((this.nextRetryTime.getTime() - System.currentTimeMillis())/1000);
        return intervalTime;
    }
 
    /**
     * 获取下一次执行时间间隔，单位s
     * @return
     */
    public int getNextConfirmExecuteTime(){
        if (this.isGreaterThanMaxConfirmCount()) {
            return 3;
        }
        int intervalTime =this.confirmCount == null ? 60 : this.confirmCount * 60;
        return intervalTime;
    }
    
    /**
     * 标记消息为待发送
     */
    public void markStatsToWaitSend() {
        this.notifyStatus = NotifyStatus.WAIT_SEND;
    }
    
    /**
     * 标记消息为已消费
     */
    public void markStatsToSuccess() {
        this.notifyStatus = NotifyStatus.SUCCESS;
    }
 
    /**
     * 标记消息为失败
     */
    public void markStatusToFail() {
        this.notifyStatus = NotifyStatus.FAIL;
    }
 
    /**
     * 标记消息为已发送
     */
    public void markStatusToSended() {
        this.notifyStatus = NotifyStatus.SENDED;
    }
 
    /**
     * 标记消息为死亡
     */
    public void markMessageToDead() {
        this.isDead = IsDead.YES;
    }
    
    /**
     * 标记消息为确认中
     */
    public void markMessageToConfirming() {
        this.notifyStatus = NotifyStatus.CONFIRMING;
    }
    
    /**
     *标记消息为被ack 
     */
    public void markMessageToAck(){
        this.notifyStatus = NotifyStatus.SUCCESS;
    }
 
    /**
     * 消息确认方式是否为rest
     * 
     * @return
     */
    public boolean cofirmWayIsRest() {
        return this.confirmWay == ConfirmWay.REST;
    }
 
    /**
     * 是否大于最大确认次数
     */
    public boolean isGreaterThanMaxConfirmCount(){
        return this.confirmCount > DEFAULT_CONFIRM_MAX_COUNT;
    }
    
    /**
     * 消息是否可以发送
     * @return
     */
    public boolean meesageIsCanSend(){
        return this.notifyStatus.getCode() < NotifyStatus.SENDED.getCode();
    }
    
    public boolean meesageStatusIsDead(){
        return this.isDead == IsDead.YES;
    }
    
    /**
     * 是否大于最大重试次数
     */
    public boolean isGreaterThanMaxRetryCount(){
        return this.retryCount > this.retryMaxCount;
    }
    
    /**
     * 构建rest消息确认方式
     * 
     * @param confirmReqUrl
     * @return
     */
    public NotifyMessage buildConfirmWayToRest(String confirmReqUrl) {
        this.confirmReqUrl = confirmReqUrl;
        return this;
    }
 
    
    /**
     * 构建消息确认方式
     * 
     * @param confirmWay消息确认方式
     * @return
     */
    public NotifyMessage buildConfirmWay(ConfirmWay confirmWay) {
        this.confirmWay = confirmWay;
        return this;
    }
 
    private static final IdWorker squeceBuild = new IdWorker(1);
    
    /**
     * 构建messageSquece
     * 
     * @return
     */
    public String buildMessageSquece() {
        return String.valueOf(squeceBuild.nextId());
    }
 
    /**
     * 初始化重试次数
     */
    private void initRetryCount() {
        this.retryCount = 0;
    }
 
    public String getMessageNo() {
        return messageNo;
    }
 
    public void setMessageNo(String messageNo) {
        if (StringUtils.isEmpty(messageNo)) {
            throw new NullPointerException("消息编号为空!");
        }
        this.messageNo = messageNo;
    }
 
    public String getMessageSquece() {
        return messageSquece;
    }
 
    public void setMessageSquece(String messageSquece) {
        if (StringUtils.isEmpty(messageSquece)) {
            throw new NullPointerException("消息序列为空!");
        }
        this.messageSquece = messageSquece;
    }
 
    public NotifyWay getNotifyWay() {
        return notifyWay;
    }
 
    public void setNotifyWay(NotifyWay notifyWay) {
        if (notifyWay == null) {
            throw new NullPointerException("消息通知方式为空!");
        }
        this.notifyWay = notifyWay;
    }
 
    /**
     * 发送http请求
     * @return
     */
    private String httpRequestSend(final String requestUrl,final String requestData){
        String requestResult = "";
        try {
            //LOGGER.info("消息序列号： "+ this.messageSquece + ",消息内容： "+ requestData);
            requestResult = HttpUtils.cs("utf-8").postJson(requestUrl,requestData );
        } catch (Exception e) {
            LOGGER.error("http请求发送异常，请求地址："+requestUrl,e);
        }
        return requestResult;
    }
    
    public String getNotifyUrl() {
        return notifyUrl;
    }
 
    public void setNotifyUrl(String notifyUrl) {
        this.notifyUrl = notifyUrl;
    }
 
    public String getNotifyData() {
        return notifyData;
    }
 
    public void setNotifyData(String notifyData) {
        this.notifyData = notifyData;
    }
 
    public Date getNextRetryTime() {
        return nextRetryTime;
    }
 
    public void setNextRetryTime(Date nextRetryTime) {
        this.nextRetryTime = nextRetryTime;
    }
 
    public NotifyDataType getNotifyDataType() {
        return notifyDataType;
    }
 
    public void setNotifyDataType(NotifyDataType notifyDataType) {
        this.notifyDataType = notifyDataType;
    }
 
    public Integer getConfirmCount() {
        return confirmCount;
    }
 
    public void setConfirmCount(Integer confirmCount) {
        this.confirmCount = confirmCount;
    }
 
    public Integer getRetryMaxCount() {
        return retryMaxCount;
    }
 
    public void setRetryMaxCount(Integer retryMaxCount) {
        this.retryMaxCount = retryMaxCount;
    }
 
    public Integer getRetryCount() {
        return retryCount;
    }
 
    public void setRetryCount(Integer retryCount) {
        this.retryCount = retryCount;
    }
 
    public NotifyStatus getNotifyStatus() {
        return notifyStatus;
    }
 
    public void setNotifyStatus(NotifyStatus notifyStatus) {
        if (notifyStatus == null) {
            throw new NullPointerException("通知状态为空!");
        }
        this.notifyStatus = notifyStatus;
    }
 
    public IsDead getIsDead() {
        return isDead;
    }
 
    public void setIsDead(IsDead isDead) {
        if (isDead == null) {
            throw new NullPointerException("是否为死亡标识为空!");
        }
        this.isDead = isDead;
    }
 
    public String getFailRemark() {
        return failRemark;
    }
 
    public void setFailRemark(String failRemark) {
        this.failRemark = failRemark;
    }
 
    public ConfirmWay getConfirmWay() {
        return confirmWay;
    }
 
    public void setConfirmWay(ConfirmWay confirmWay) {
        this.confirmWay = confirmWay;
    }
 
    public String getConfirmReqUrl() {
        return confirmReqUrl;
    }
 
    public void setConfirmReqUrl(String confirmReqUrl) {
        this.confirmReqUrl = confirmReqUrl;
    }
 
    public Date getCreateDate() {
        return createDate;
    }
 
    public void setCreateDate(Date createDate) {
        if (createDate == null) {
            throw new NullPointerException("创建时间为空!");
        }
        this.createDate = createDate;
    }
 
    public Date getUpdateDate() {
        return updateDate;
    }
 
    public void setUpdateDate(Date updateDate) {
        if (updateDate == null) {
            throw new NullPointerException("更新时间为空!");
        }
        this.updateDate = updateDate;
    }
 
    public Integer getDeleteFlag() {
        return deleteFlag;
    }
 
    public void setDeleteFlag(Integer deleteFlag) {
        this.deleteFlag = deleteFlag;
    }
    
    /**
     * 消息确认结果
     * 
     * @author yilin
     *
     */
    static class ConfirmResult {
 
        private static final String SUCESS_TAG = "0000";
 
        private static final String FAIL_TAG = "9999";
 
        private String code;
 
        private String message;
 
        private MessageConfirmStatus messageConfirmStatus;
 
        public static final ConfirmResult FAIL = new ConfirmResult("9999", "消息确认失败!");
 
        public ConfirmResult() {
        }
 
        public ConfirmResult(String code, String message) {
            this.code = code;
            this.message = message;
        }
 
        public ConfirmResult(String code, String message, MessageConfirmStatus messageConfirmStatus) {
            this.code = code;
            this.message = message;
            this.messageConfirmStatus = messageConfirmStatus;
        }
 
        public String getCode() {
            return code;
        }
 
        public void setCode(String code) {
            this.code = code;
        }
 
        public String getMessage() {
            return message;
        }
 
        public void setMessage(String message) {
            this.message = message;
        }
 
        public MessageConfirmStatus getMessageConfirmStatus() {
            return messageConfirmStatus;
        }
 
        public void setMessageConfirmStatus(MessageConfirmStatus messageConfirmStatus) {
            this.messageConfirmStatus = messageConfirmStatus;
        }
 
        /**
         * 是否调用成功
         * 
         * @return
         */
        public boolean isSuccess() {
            return this.code.equals(SUCESS_TAG);
        }
        
        /**
         * 消息是否需要发送
         * 
         * @return
         */
        public boolean messageIsNeedSend() {
            return this.messageConfirmStatus == MessageConfirmStatus.TURE;
        }
    }
    
    /**
     * 消息发送结果
     * @author yilin
     *
     */
    static class MessagSendResult{
        private String  resultCode;
        private String resultMsg;
        private int ackFlag;
        
        public MessagSendResult(String resultCode, String resultMsg, int ackFlag) {
            this.resultCode = resultCode;
            this.resultMsg = resultMsg;
            this.ackFlag = ackFlag;
        }
        
        public MessagSendResult(String resultCode, String resultMsg) {
            this.resultCode = resultCode;
            this.resultMsg = resultMsg;
        }
        
        public String getResultCode() {
            return resultCode;
        }
        
        public void setResultCode(String resultCode) {
            this.resultCode = resultCode;
        }
        public String getResultMsg() {
            return resultMsg;
        }
        public void setResultMsg(String resultMsg) {
            this.resultMsg = resultMsg;
        }
        public int getAckFlag() {
            return ackFlag;
        }
        public void setAckFlag(int ackFlag) {
            this.ackFlag = ackFlag;
        }
        
        public boolean isSuccess(){
            return this.resultCode.equals("0000");
        }
        
        public boolean isNeedAck(){
            return this.ackFlag == ACKFlag.NEED.getCode();
        }
    }
 
}
